"""
Copyright Alex Susu 2011-2012
"""

import os
import sys
import time
import thread
import threading
import traceback

import objc



iOS_PYOBJC = True
MY_DEBUG_STDOUT = True
MY_DEBUG_STDERR = True

LOCAL_FOLDER = "/var/mobile/iCam"
STDERR_FILENAME_PREFIX = "stderr_HP_"
STDOUT_FILENAME_PREFIX = "stdout_HP_"

def GetCurrentDateTime():
    return time.localtime()


stdoutFile = None
stderrFile = None
stdoutFileName = None
stderrFileName = None
def CreateDirectoriesAndLogFiles():
    global stdoutFile, stderrFile
    global stdoutFileName, stderrFileName
    global LOCAL_FOLDER

    try:
        if not os.path.exists(LOCAL_FOLDER):
            os.makedirs(LOCAL_FOLDER)

        STDDateTime = time.strftime("%Y_%m_%d_%H_%M_%S", GetCurrentDateTime())
        #STDDateTime = "HP"

        if (MY_DEBUG_STDOUT):
            sys.stdout.flush()
            stdoutFileName = STDOUT_FILENAME_PREFIX + STDDateTime + ".txt"
            stdoutFile = open(LOCAL_FOLDER + "/" + stdoutFileName, "a")
            sys.stdout = stdoutFile
            sys.stdout.flush()

        if (MY_DEBUG_STDERR):
            sys.stderr.flush()
            stderrFileName = STDERR_FILENAME_PREFIX + STDDateTime + ".txt"
            stderrFile = open(LOCAL_FOLDER + "/" + stderrFileName, "a")
            sys.stderr = stderrFile
            sys.stderr.flush()
    except:
        if (MY_DEBUG_STDERR):
            traceback.print_exc()
            sys.stderr.flush()
CreateDirectoriesAndLogFiles()



myUIKit = objc.loadBundle("UIKit", globals(), "/System/Library/Frameworks/UIKit.framework")
ipc = UIImagePickerController.alloc().init() #I defined it here because like this it "loads" the protocol UIImagePickerControllerDelegate
if (MY_DEBUG_STDOUT):
    print "After loadBundle UIKit: objc.protocolsForProcess() = %s with len %d" % (str(objc.protocolsForProcess()), len(objc.protocolsForProcess()))
    print "    dir() = %s and len(dir()) = %d." % (str(dir()), len(dir()))
    print "    UIImagePickerController.pyobjc_classMethods = %s" % (str(UIImagePickerController.pyobjc_classMethods))
    print "    dir(UIImagePickerController) = %s" % (str(dir(UIImagePickerController)))
    print "    objc.protocolsForClass(UIImagePickerController) = %s" % (str(objc.protocolsForClass(UIImagePickerController)))
    sys.stdout.flush()
UINavigationControllerDelegate = objc.protocolNamed("UINavigationControllerDelegate")
UIImagePickerControllerDelegate = objc.protocolNamed("UIImagePickerControllerDelegate")
if (MY_DEBUG_STDOUT):
    print "UINavigationControllerDelegate = %s" % (str(UINavigationControllerDelegate))
    print "UIImagePickerControllerDelegate = %s" % (str(UIImagePickerControllerDelegate))
    sys.stdout.flush()

objc.loadBundle("AVFoundation", globals(), "/System/Library/Frameworks/AVFoundation.framework")
if (MY_DEBUG_STDOUT):
    print "After loadBundle AVFoundation: objc.protocolsForProcess() = %s with len %d" % (str(objc.protocolsForProcess()), len(objc.protocolsForProcess()))
    print "    dir() = %s and len(dir()) = %d." % (str(dir()), len(dir()))
    sys.stdout.flush()



#import a
a = None

class TestBedViewController(UIViewController, UINavigationControllerDelegate, UIImagePickerControllerDelegate):

    #See http://developer.apple.com/library/ios/#DOCUMENTATION/UIKit/Reference/UIImagePickerControllerDelegate_Protocol/UIImagePickerControllerDelegate/UIImagePickerControllerDelegate.html
    #- (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
    @objc.signature("v@:@@")
    def imagePickerController_didFinishPickingMediaWithInfo_(self, picker, info):
        try:
            if (MY_DEBUG_STDOUT):
                print "!Entered imagePickerController_didFinishPickingMediaWithInfo_(self, picker = %s, info = %s)." % (str(picker), str(info))
                sys.stdout.flush()

            """
            From Recipe 7.5:
            // Retrieve the selected image
            UIImage *image = [info objectForKey:
                @"UIImagePickerControllerOriginalImage"];
            [self dismissModalViewControllerAnimated:YES];
            [picker release];

            // Write it to file
            [UIImageJPEGRepresentation(image, 1.0f) writeToFile:
                [self findUniqueSavePath] atomically:YES];

            // Set the background
            SETIMAGE(image);
            // Show the current contents of the documents folder
            CFShow([[NSFileManager defaultManager]
                directoryContentsAtPath:[NSHomeDirectory()
                stringByAppendingString:@"/Documents"]]);
            """

            image = info["UIImagePickerControllerOriginalImage"]
            if (MY_DEBUG_STDOUT):
                print "imagePickerController_didFinishPickingMediaWithInfo_(): image = %s." % (str(image))
                sys.stdout.flush()
            #UIImageJPEGRepresentation(image, 1.0).writeToFile_atomically_("bla.jpg", objc.YES)
            #UIImageJPEGRepresentation(image, 1.0).writeToFile_atomically_("/var/mobile/Media/DCIM/100APPLE/temp.jpg", objc.YES) #It takes ~5 secs on iPhone 2G.
            photoPathFileName = "/var/mobile/iCam/Media/" + a.GetCurrentDateTimeStringWithMilliseconds() + "_0.jpg"

            """
            From http://developer.apple.com/library/ios/#DOCUMENTATION/UIKit/Reference/UIKitFunctionReference/Reference/reference.html#//apple_ref/c/func/UIImageJPEGRepresentation
            NSData * UIImageJPEGRepresentation (
               UIImage *image,
               CGFloat compressionQuality
            );

            Parameters
            image
                The original image data. 
            compressionQuality
                The quality of the resulting JPEG image, expressed as a value from 0.0 to 1.0. The value 0.0 represents the maximum compression (or lowest quality) while the value 1.0 represents the least compression (or best quality).
            """
            #UIImageJPEGRepresentation(image, 1.0).writeToFile_atomically_(photoPathFileName, objc.YES) #It takes ~5 secs on iPhone 2G. ~2 MB.
            UIImageJPEGRepresentation(image, 0.1).writeToFile_atomically_(photoPathFileName, objc.YES) #It takes ~5 secs on iPhone 2G. ~43 KB
            a.lastiOSTakePicturePhotoPathFileName = photoPathFileName

            if (MY_DEBUG_STDOUT):
                print "imagePickerController_didFinishPickingMediaWithInfo_(): Finished saving the JPEG."
                sys.stdout.flush()
        except:
            traceback.print_exc()
            sys.stderr.flush()

    #Provide 2.x compliance
    #- (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image editingInfo:(NSDictionary *)editingInfo
    @objc.signature("v@:@@@")
    def imagePickerController_didFinishPickingImage_editingInfo_(self, picker, image, editingInfo):
        try:
            print "!Entered."
            sys.stdout.flush()
            print "!Entered imagePickerController_didFinishPickingImage_editingInfo_(self, picker = %s, image = %s, editingInfo = %s)." % (str(picker), str(image), str(editingInfo))
            sys.stdout.flush()

            #NSDictionary *dict = [NSDictionary dictionaryWithObject:image forKey:@"UIImagePickerControllerOriginalImage"];
            self.imagePickerController_didFinishPickingMediaWithInfo_(picker, dict)
        except:
            traceback.print_exc()
            sys.stderr.flush()

    #- (void) imagePickerControllerDidCancel: 
    @objc.signature("v@:@")
    def imagePickerControllerDidCancel_(self, picker):
        try:
            print "!Entered."
            sys.stdout.flush()
            print "!Entered imagePickerControllerDidCancel_(self, picker = %s)." % (str(picker))
            sys.stdout.flush()

            self.dismissModalViewControllerAnimated_(objc.YES)
            #picker.release()
        except:
            traceback.print_exc()
            sys.stderr.flush()











    UIImagePickerControllerSourceTypeCamera = 1
    def MyIPC(self):
        global ipc

        #time.sleep(2.0) #7.0)

        try:
            if (ipc == None):
                ipc = UIImagePickerController.alloc().init()

            if (MY_DEBUG_STDOUT):
                print "MyIPC(): ipc =", ipc
                sys.stdout.flush()

            if (MY_DEBUG_STDOUT):
                print "MyIPC(): self.UIImagePickerControllerSourceTypeCamera =", self.UIImagePickerControllerSourceTypeCamera
                sys.stdout.flush()
            """
            #See http://developer.apple.com/library/ios/#documentation/uikit/reference/UIImagePickerController_Class/UIImagePickerController/UIImagePickerController.html#//apple_ref/doc/c_ref/UIImagePickerControllerSourceTypeCamera
            enum {
               UIImagePickerControllerSourceTypePhotoLibrary,
               UIImagePickerControllerSourceTypeCamera,
               UIImagePickerControllerSourceTypeSavedPhotosAlbum
            };
            typedef NSUInteger UIImagePickerControllerSourceType;

            sourceType
            The type of picker interface to be displayed by the controller.
            @property(nonatomic) UIImagePickerControllerSourceType sourceType
            """

            if (MY_DEBUG_STDOUT):
                print "MyIPC(): ipc.sourceType = %s, ipc._.sourceType = %s" % (str(ipc.sourceType), str(ipc._.sourceType))
                sys.stdout.flush()
            ipc.setSourceType_(self.UIImagePickerControllerSourceTypeCamera)
            if (MY_DEBUG_STDOUT):
                print "MyIPC(): ipc._.sourceType =", ipc._.sourceType
                sys.stdout.flush()

            if (MY_DEBUG_STDOUT):
                print "MyIPC(): ipc.delegate = %s, ipc._.delegate = %s" % (str(ipc.delegate), str(ipc._.delegate))
                sys.stdout.flush()

            ipc.setDelegate_(self)

            if (MY_DEBUG_STDOUT):
                print "MyIPC(): ipc._.delegate = %s" % (str(ipc._.delegate))
                sys.stdout.flush()

            if (MY_DEBUG_STDOUT):
                print "MyIPC(): ipc.allowsImageEditing = %s, ipc._.allowsImageEditing = %s" % (str(ipc.allowsImageEditing), str(ipc._.allowsImageEditing))
                sys.stdout.flush()
            ipc.setAllowsImageEditing_(objc.NO)

            #ipc._.allowsEditing = objc.NO #in 3.1
            ipc.setAllowsEditing_(objc.NO)
            if (MY_DEBUG_STDOUT):
                print "MyIPC(): ipc._.allowsEditing = %s" % (str(ipc._.allowsEditing))
                sys.stdout.flush()




            #AUTOMATIC = False
            AUTOMATIC = True

            if (AUTOMATIC):
                #ipc._.showsCameraControls = objc.NO #This is necessary to use ipc.takePicture(). (From "Recipe: Capturing Time Lapse Photos")
                ipc.setShowsCameraControls_(objc.NO)
                if (MY_DEBUG_STDOUT):
                    #From http://developer.apple.com/library/ios/documentation/uikit/reference/UIImagePickerController_Class/UIImagePickerController/UIImagePickerController.html#//apple_ref/occ/clm/UIImagePickerController/availableMediaTypesForSourceType: : + (NSArray *)availableMediaTypesForSourceType:(UIImagePickerControllerSourceType)sourceType
                    print "MyIPC(): ipc._.showsCameraControls = %s" % (str(ipc._.showsCameraControls))
                    sys.stdout.flush()





            """
            From http://developer.apple.com/library/mac/#documentation/GraphicsImaging/Conceptual/ImageIOGuide/imageio_basics/ikpg_basics.html
                public.image kUTTypeImage
                public.png kUTTypePNG
                public.jpeg kUTTypeJPEG
                public.jpeg-2000 (Mac OS X only)
                kUTTypeJPEG2000
                public.tiff kUTTypeTIFF
                com.apple.pict (Mac OS X only) kUTTypePICT
                com.compuserve.gif kUTTypeGIF
            """
            if (MY_DEBUG_STDOUT):
                #From http://developer.apple.com/library/ios/documentation/uikit/reference/UIImagePickerController_Class/UIImagePickerController/UIImagePickerController.html#//apple_ref/occ/clm/UIImagePickerController/availableMediaTypesForSourceType: : + (NSArray *)availableMediaTypesForSourceType:(UIImagePickerControllerSourceType)sourceType
                print "MyIPC(): ipc._.mediaTypes = %s" % (str(ipc._.mediaTypes))
                sys.stdout.flush()
            """
            Don't understand why: "Available in iOS 3.0 and later." (from http://developer.apple.com/library/ios/documentation/uikit/reference/UIImagePickerController_Class/UIImagePickerController/UIImagePickerController.html#//apple_ref/occ/clm/UIImagePickerController/availableMediaTypesForSourceType:)
            #AttributeError: 'UIImagePickerController' object has no attribute 'availableMediaTypesForSourceType_'
            #+ (NSArray *)availableMediaTypesForSourceType:(UIImagePickerControllerSourceType)sourceType
            if (MY_DEBUG_STDOUT):
                print "MyIPC(): ipc.availableMediaTypesForSourceType_(1) = %s" % (str(ipc.availableMediaTypesForSourceType_(1)))
                sys.stdout.flush()
            """

            #selfTestBedViewController.presentModalViewController_animated_(ipc, objc.YES)
            self.presentModalViewController_animated_(ipc, objc.YES)

            #time.sleep(2.0) #7.0)

            if (AUTOMATIC):
                if (MY_DEBUG_STDOUT):
                    print "MyIPC(): Setting timer to call ipc.takePicture, at time.time() = %.2f." % (time.time())
                    sys.stdout.flush()

                """
                // Wait for camera set up and then snap a picture
                [NSTimer scheduledTimerWithTimeInterval:2.0f target:ipc selector:@selector(takePicture) userInfo:nil repeats:NO];
                """
                #From http://lethain.com/how-to-use-selectors-in-pyobjc/
                #It seems it crashes the HelloPython app: myNSTimer = NSTimer.scheduledTimerWithTimeInterval_target_selector_userInfo_repeats_(5.0, ipc, objc.selector(ipc.takePicture, signature = "v@:"), objc.nil, objc.NO)
                #####myNSTimer.invalidate()
                threading.Timer(3.0, ipc.takePicture).start() #WORKS

                #myNSTimer = NSTimer.scheduledTimerWithTimeInterval_target_selector_userInfo_repeats_(30.0, self, objc.selector(self.MyIPC, signature = "v@:"), objc.nil, objc.NO)

            """
            if (MY_DEBUG_STDOUT):
                print "MyIPC(): before ipc.takePicture()."
                sys.stdout.flush()
            ipc.takePicture()
            if (MY_DEBUG_STDOUT):
                print "MyIPC(): after ipc.takePicture()."
                sys.stdout.flush()
            """


            if (MY_DEBUG_STDOUT):
                print "Exiting MyIPC()."
                sys.stdout.flush()
        except:
            if (MY_DEBUG_STDERR):
                traceback.print_exc()
                sys.stderr.flush()


    def TimedCallMyIPC(self):
        try:
            if (True):
                if (MY_DEBUG_STDOUT):
                    print "Setting timer to call self.MyIPC(), at time.time() = %.2f." % (time.time())
                    sys.stdout.flush()
                """
                From Recipe 7.5:
                // Wait for camera set up and then snap a picture
                [NSTimer scheduledTimerWithTimeInterval:2.0f target:ipc
                    selector:@selector(takePicture) userInfo:nil repeats:NO];
                """
                #From http://lethain.com/how-to-use-selectors-in-pyobjc/
                myNSTimer = NSTimer.scheduledTimerWithTimeInterval_target_selector_userInfo_repeats_(5.0, self, objc.selector(self.MyIPC, signature = "v@:"), objc.nil, objc.NO)
                #threading.Timer(8.0, self.MyIPC).start() #This doesn't display the ViewFinder --> no photo is taken nor saved.
        except:
            if (MY_DEBUG_STDERR):
                traceback.print_exc()
                sys.stderr.flush()


    #- (void) snapImage: (id) sender
    @objc.signature("v@:@")
    def snapImage_(self, sender):
        print "Entered snapImage_(self, sender = %s)." % (str(sender))
        sys.stdout.flush()
        try:
            self.MyIPC()
            #pass
        except:
            traceback.print_exc()
            sys.stderr.flush()


    #IMPORTANT NOTE: I recommend executing ALL/PART OF this code in loadView() and NOT in viewDidLoad().
    #- (void)loadView
    @objc.signature("v@:")
    def loadView(self):
        #global testBedViewControllerInstance
        global a
        import a
        a.testBedViewControllerInstance = self
        a.NSTimer = NSTimer

        if (MY_DEBUG_STDOUT):
            print "Entered loadView()."
            sys.stdout.flush()

        if (MY_DEBUG_STDOUT):
            print "    dir(TestBedViewController) = %s" % (str(dir(TestBedViewController)))
            print "    objc.protocolsForClass(TestBedViewController) = %s" % (str(objc.protocolsForClass(TestBedViewController)))
            sys.stdout.flush()

        #return

        try:
            """
            UIView *contentView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
            self.view = contentView;
            contentView.backgroundColor = [UIColor whiteColor];
            [contentView release];
            
            UIImageView *iv = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"cover320x416.png"]];
            [self.view addSubview:iv];
            iv.userInteractionEnabled = YES;
            """

            contentView = UIView.alloc().initWithFrame_(UIScreen.mainScreen().applicationFrame())
    
            self.setView_(contentView)


            contentView.setBackgroundColor_(UIColor.whiteColor())
            #if (True):
            if (False):
                """
                This crashes the application in PyObjC, BUT NOT the one in ObjectiveC
                """
                contentView.release()

            #iv = [ UIImageView.alloc().initWithImage_(UIImage.imageNamed_(u"cover320x416.png"))
            iv = UIImageView.alloc()
            #iv = UIImageView.alloc().initWithImage_(UIImage.imageNamed_(u"/Applications/HelloPython.app/cover320x416.png")) #Doesn't load the image
            self._.view.addSubview_(iv)
            iv.setUserInteractionEnabled_(objc.YES)

            if (False):
                if (UIImagePickerController.isSourceTypeAvailable_(1)):
                    self._.navigationController._.navigationBar.setTintColor_(UIColor.colorWithRed_green_blue_alpha_(0.20392, 0.19607, 0.61176, 1.0))

                    if (MY_DEBUG_STDOUT):
                        print "loadView(): self._.navigationController._.navigationBar._.tintColor = %s" % (str(self._.navigationController._.navigationBar._.tintColor))
                        sys.stdout.flush()

                self.setTitle_(u"iCam")

                if (MY_DEBUG_STDOUT):
                    print "loadView(): after, self.title() = %s" % (str(self.title()))
                    print "loadView(): after, self._.title = %s" % (str(self._.title))
                    sys.stdout.flush()

                if (MY_DEBUG_STDOUT):
                    print "loadView(): self._.navigationItem._.rightBarButtonItem = %s" % (str(self._.navigationItem._.rightBarButtonItem))
                    print "loadView(): self._.navigationItem.rightBarButtonItem = %s" % (str(self._.navigationItem.rightBarButtonItem))
                    sys.stdout.flush()

                #OBJECTIVE C CODE: self.navigationItem.rightBarButtonItem = BARBUTTON(@"Snap", @selector(snapImage:));
                self._.navigationItem._.rightBarButtonItem = UIBarButtonItem.alloc().initWithTitle_style_target_action_(u"Snap", 0, self, objc.selector(self.snapImage_, signature = "v@:@"))

                #self._.navigationItem.setRightBarButtonItem_(UIBarButtonItem.alloc().initWithTitle_style_target_action_(u"Snap", 0, self, objc.selector(self.snapImage_, signature = "v@:@")).autorelease())

            #thread.start_new_thread(self.MyIPC, ()) #This DOES NOT show the viewfinder after taking photo.
            #self.MyIPC() #This shows the viewfinder after taking photo. But in another case, it crashed program (with MyDelegate)

            if (True): #False):
                if (MY_DEBUG_STDOUT):
                    print "Setting timer to call self.MyIPC(), at time.time() = %.2f." % (time.time())
                    sys.stdout.flush()
                """
                From Recipe 7.5:
                // Wait for camera set up and then snap a picture
                [NSTimer scheduledTimerWithTimeInterval:2.0f target:ipc
                    selector:@selector(takePicture) userInfo:nil repeats:NO];
                """
                #From http://lethain.com/how-to-use-selectors-in-pyobjc/
                if (True): #False):
                    """
                    #Works nicely for hours
                    myNSTimer = NSTimer.scheduledTimerWithTimeInterval_target_selector_userInfo_repeats_(15.0, self, objc.selector(self.MyIPC, signature = "v@:"), objc.nil, objc.YES) #, objc.NO)
                    """
                    myNSTimer = NSTimer.scheduledTimerWithTimeInterval_target_selector_userInfo_repeats_(20.0, self, objc.selector(self.MyIPC, signature = "v@:"), objc.nil, objc.YES) #, objc.NO)
                #threading.Timer(8.0, self.MyIPC).start() #This doesn't display the ViewFinder --> no photo is taken nor saved.

            thread.start_new_thread(a.Main, ())

            if (MY_DEBUG_STDOUT):
                print "Exiting loadView()."
                sys.stdout.flush()
        except:
            if (MY_DEBUG_STDERR):
                traceback.print_exc()
                sys.stderr.flush()

    #- (void) viewDidLoad
    @objc.signature("v@:")
    def viewDidLoad(self):
        try:
            if (MY_DEBUG_STDOUT):
                #print "Entered viewDidLoad()."
                sys.stdout.flush()
        except:
            if (MY_DEBUG_STDERR):
                traceback.print_exc()
                sys.stderr.flush()

    """
    #- (void) viewDidLoad
    @objc.signature("v@:")
    def viewDidLoad(self):
        try:
            if (UIImagePickerController.isSourceTypeAvailable_(1)):
                self._.navigationController._.navigationBar.setTintColor_(UIColor.colorWithRed_green_blue_alpha_(0.20392, 0.19607, 0.61176, 1.0))

            self.setTitle_(u"Image Picker")

            #thread.start_new_thread(self.MyIPC, ())
        except:
            traceback.print_exc()
            sys.stderr.flush()
    """


"""
UIApplicationDelegate = objc.informal_protocol("UIApplicationDelegate", [
    #- (void)applicationDidFinishLaunching:(UIApplication *)application
    objc.selector(None, selector = "applicationDidFinishLaunching:", signature = "v@:@") #ValueError: NSInvalidArgumentException - *** +[TestBedAppDelegate registerForSystemEvents]: unrecognized selector sent to class 0x2df900
])
"""

class TestBedAppDelegate(NSObject):
    @objc.signature("v@:@")
    def applicationDidFinishLaunching_(self, application):
        try:
            if (MY_DEBUG_STDOUT):
                print "applicationDidFinishLaunching_(): trying new stuff 8 ;)."
                sys.stdout.flush()

            """
            outer = UIHardware.fullScreenApplicationContentRect()
            self.window = UIWindow.alloc().initWithFrame_(outer)

            self.window.orderFront_(self)
            self.window.makeKey_(self)
            self.window.setHidden_(NO)

            inner = self.window.bounds()
            navsize = UINavigationBar.defaultSize()
            navrect = ((0, 0), (inner[1][0], navsize[1]))

            self.view = UIView.alloc().initWithFrame_(self.window.bounds())
            self.window.setContentView_(self.view)
            """

            if (False):
                self.window = UIWindow.alloc().initWithFrame_(UIScreen.mainScreen().bounds()) #Another WORKING option: self.window = UIWindow.alloc().initWithFrame_(UIHardware.fullScreenApplicationContentRect())
                nav = UINavigationController.alloc().initWithRootViewController_(TestBedViewController.alloc().init())

                self.window.addSubview_(nav._.view) #I received UninitializedDeallocWarning: leaking an uninitialized object of type UIImageView, when I gave iv = UIImageView.alloc()
                self.window.makeKeyAndVisible()
            else:
                self.window = UIWindow.alloc().initWithFrame_(UIHardware.fullScreenApplicationContentRect())
                self.window.orderFront_(self)
                self.window.makeKey_(self)
                self.window.setHidden_(objc.NO)

                inner = self.window.bounds()
                navsize = UINavigationBar.defaultSize()
                navrect = ((0, 0), (inner[1][0], navsize[1]))

                self.view = UIView.alloc().initWithFrame_(self.window.bounds())
                self.window.setContentView_(self.view)

                """
                self.navbar = UINavigationBar.alloc().initWithFrame_(navrect);
                self.view.addSubview_(self.navbar)

                self.navbar.setBarStyle_(1)

                navitem = UINavigationItem.alloc().initWithTitle_("Contact List")
                self.navbar.pushNavigationItem_(navitem)
                """

                self.nav = UINavigationController.alloc().initWithRootViewController_(TestBedViewController.alloc().init())

                self.view.addSubview_(self.nav._.view)

                #MyIPC() #In one case it crashed after taking photo - probably because I wasn't instantiating properly MyDelegate.
                #thread.start_new_thread(MyIPC, ()) #This DOES NOT show the viewfinder after taking photo.

                #self.window.addSubview_(self.nav._.view) #I received UninitializedDeallocWarning: leaking an uninitialized object of type UIImageView, probably because of iv = UIImageView.alloc()
                #self.window.makeKeyAndVisible()


            """
            #Inspired from original:
            outer = UIHardware.fullScreenApplicationContentRect()
            window = UIWindow.alloc().initWithFrame_(outer.bounds())
            """


            """
            window.orderFront_(self)
            window.makeKey_(self)
            window.setHidden_(objc.NO)
            """
        except:
            traceback.print_exc()
            sys.stderr.flush()


"""
Note:
Have tried also using the standard:
    retVal = _uicaboodle.UIApplicationMain(sys.argv, TestBedAppDelegate)
and I had:
    class TestBedAppDelegate(UIApplication):
This does not solve the problem, and in fact is not how it's done in the book chapter.
"""


#newVersion = False
newVersion = True

if (newVersion):
    #From http://www.telesphoreo.org/pipermail/iphone-python/2008-July/000058.html
    """
    From http://developer.apple.com/library/ios/#DOCUMENTATION/UIKit/Reference/UIKitFunctionReference/Reference/reference.html:
    int UIApplicationMain (
       int argc,
       char *argv[],
       NSString *principalClassName,
       NSString *delegateClassName
    );

    NSData * UIImageJPEGRepresentation (
       UIImage *image,
       CGFloat compressionQuality #From http://stackoverflow.com/questions/1264924/whats-the-difference-between-using-cgfloat-and-float: "CGFloat is a regular float on 32-bit systems and a double on 64-bit systems"
    );
    """
    objc.loadBundleFunctions(myUIKit, globals(), [
        ("UIApplicationMain", "iii@@"),
        ("UIImageJPEGRepresentation", "@@f"),
    ])

    _UIApplicationMain = UIApplicationMain
    def UIApplicationMain(argv = None, principal = objc.nil, delegate = None):
        print "Entered UIApplicationMain()."
        sys.stdout.flush()

        if (argv == None):
            argv = sys.argv
        
        from ctypes import c_char_p, addressof
        argc = len(argv)
        argv = (c_char_p * argc)(*argv)
        
        if (delegate is None):
            delegate = principal

        if (principal != objc.nil):
            principal = NSString.alloc().initWithString_(principal.__name__)
        if (delegate != objc.nil):
            delegate = NSString.alloc().initWithString_(delegate.__name__)
        
        return _UIApplicationMain(argc, addressof(argv), principal, delegate)



#pool = NSAutoreleasePool.alloc().init()

if (newVersion):
    retVal = UIApplicationMain(sys.argv, objc.nil, TestBedAppDelegate)
else:
    import _uicaboodle
    _uicaboodle.UIApplicationMain(sys.argv, TestBedAppDelegate)

print "retVal = %s" % (str(retVal))
sys.stdout.flush()

#pool.release()
